﻿using Furion.DatabaseAccessor;
using Furion.DependencyInjection;
using FurionApiDemo.Core.Entity;
using FurionApiDemo.Core.Manager;
using FurionApiDemo.Core.Implementt.User.Dtos;
using Mapster;
using Microsoft.EntityFrameworkCore;
using System;
using System.Threading.Tasks;
using FurionApiDemo.Core.ApiResult;
using Microsoft.Extensions.Logging;
using FurionApiDemo.Core.Manager.User;
using System.Collections.Generic;
using System.Linq;
using FurionApiDemo.Core.Implement.User.Dtos;
using FurionApiDemo.Core.Implement;
using Furion.DataEncryption;

namespace FurionApiDemo.Core
{
    public class UserService : IUserService, ITransient
    {
        private readonly IRepository<SysUser> _sysUserRep;  // 用户表仓储 
        private readonly IRepository<SysUserInfo> _sysUserInfoRep;  // 用户表仓储 
        private readonly IRepository<SysUserRole> _sysUserRoleRep;  // 用户表仓储 
        private readonly IUserManager _userManager;

        private readonly IRoleService _sysRoleService;
        private readonly UserRoleService _userRoleService;

        private readonly ILogger<UserService> _logger;

        public UserService(IRepository<SysUser> sysUserRep,
            IRepository<SysUserInfo> sysUserInfoRep,
            IUserManager userManager,
            ILogger<UserService> logger,
            IRoleService sysRoleService,
            IRepository<SysUserRole> sysUserRoleRep,
            UserRoleService userRoleService)
        {
            _sysUserRep = sysUserRep;
            _sysUserInfoRep = sysUserInfoRep;
            _userManager = userManager;
            _sysRoleService = sysRoleService;
            _sysUserRoleRep = sysUserRoleRep;
            _userRoleService = userRoleService;
        }

        /// <summary>
        /// 获取当前用户信息
        /// </summary>
        /// <returns></returns>
        public async Task<UserOutput> GetUser()
        {
            var userM = _userManager.User;
            var user = userM.Adapt<UserOutput>();
            var userInfo = await _sysUserInfoRep.DetachedEntities.FirstOrDefaultAsync(u => u.UserId == _userManager.UserId);
            user.UserInfo = userInfo.Adapt<UserInfoOutput>();
            return user;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<UserOutput> GetUser(UserInput input)
        {
            var userM = await _sysUserRep.DetachedEntities.FirstOrDefaultAsync(u => u.Id == long.Parse(input.Id));
            var user = userM.Adapt<UserOutput>();
            var userInfo = await _sysUserInfoRep.DetachedEntities.FirstOrDefaultAsync(u => u.UserId == long.Parse(input.Id));
            user.UserInfo = userInfo.Adapt<UserInfoOutput>();
            return user;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<UserOutput> GetUser(long id)
        {
            SysUser userM = await _sysUserRep.AsQueryable().Include(t => t.SysUserInfo).Include(t => t.SysUserRoles).ThenInclude(t => t.SysRole).FirstOrDefaultAsync(u => u.Id == id);
            var user = userM.Adapt<UserOutput>();
            user.UserInfo = userM.SysUserInfo.Adapt<UserInfoOutput>();
            user.UserRole = new List<RoleOutput>();
            var list = userM.SysUserRoles.ToList();
            for (int i = 0; i < list.Count; i++)
            {
                user.UserRole.Add(list[i].SysRole.Adapt<RoleOutput>());
            }
            //user.UserRole = await _sysRoleService.GetUserRoleList(id);
            return user;
        }

        /// <summary>
        /// 查询用户列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedList<UserListOutput>> GetUserList(UserListInput input)
        {
            var userName = !string.IsNullOrEmpty(input.UserName?.Trim());
            var nickName = !string.IsNullOrEmpty(input.NickName?.Trim());
            var phone = !string.IsNullOrEmpty(input.Phone?.Trim());
            var email = !string.IsNullOrEmpty(input.Email?.Trim());
            var keyWord = !string.IsNullOrEmpty(input.KeyWord?.Trim());
            var userM = await _sysUserRep.DetachedEntities
                .Where((userName, u => EF.Functions.Like(u.UserName, $"%{input.UserName.Trim()}%")),
                        (nickName, u => EF.Functions.Like(u.SysUserInfo.NickName, $"%{input.NickName.Trim()}%")),
                        (phone, u => EF.Functions.Like(u.SysUserInfo.Phone, $"%{input.Phone.Trim()}%")),
                        (email, u => EF.Functions.Like(u.SysUserInfo.Email, $"%{input.Email.Trim()}%")))
                .Where((keyWord, u => EF.Functions.Like(u.UserName, $"%{input.KeyWord}%")),
                        (keyWord, u => EF.Functions.Like(u.SysUserInfo.NickName, $"%{input.KeyWord}%")),
                        (keyWord, u => EF.Functions.Like(u.SysUserInfo.Phone, $"%{input.KeyWord}%")),
                        (keyWord, u => EF.Functions.Like(u.SysUserInfo.Email, $"%{input.KeyWord}%")))
                .Where(t => t.IsDeleted == false)
                .Select(d => new UserListOutput
                {
                    Id = d.Id,
                    Status = d.Status,
                    AvatarUrl = d.SysUserInfo.AvatarUrl,
                    Birthday = d.SysUserInfo.Birthday,
                    Email = d.SysUserInfo.Email,
                    NickName = d.SysUserInfo.NickName,
                    Phone = d.SysUserInfo.Phone,
                    Sex = d.SysUserInfo.Sex,
                    UserName = d.UserName,
                    CreateTime = d.CreatedTime.Value.ToString("yyyy-MM-dd hh:mm:ss")
                })
                .ToPagedListAsync(input.PageNo, input.PageSize);
            return userM;
        }

        /// <summary>
        /// 保存用户信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SaveUser(SaveUserInput input)
        {
            SysUser user = new SysUser();
            if (input.Id.HasValue)
            {
                //更新
                user = await _sysUserRep.AsQueryable().Include(t => t.SysUserInfo).Include(t => t.SysUserRoles).FirstOrDefaultAsync(t => t.Id == input.Id);
            }
            else
            {
                user.SysUserInfo = new SysUserInfo();
                if (await _sysUserRep.AnyAsync(t => t.UserName == input.UserName))
                {
                    throw new Exception("用户名重复");
                }
            }
            user.UserName = input.UserName;
            user.Status = (int)input.Status;
            user.AdminType = (int)AdminType.None;
            SysUserInfo userInfo = new SysUserInfo();
            user.SysUserInfo.NickName = input.NickName;
            user.SysUserInfo.Phone = input.Phone;
            user.SysUserInfo.Sex = (int)input.Sex;
            user.SysUserInfo.Email = input.Email;
            if (input.Birthday.HasValue)
            {
                user.SysUserInfo.Birthday = input.Birthday.Value;
            }
            user.SysUserInfo.AvatarUrl = input.Avatar;
            var userId = input.Id;
            if (input.Id.HasValue)
            {
                //更新
                await _sysUserRep.UpdateAsync(user);
                await _sysUserInfoRep.UpdateAsync(user.SysUserInfo);
            }
            else
            {
                //新增
                user.Password = MD5Encryption.Encrypt("123456");
                var backUser = await _sysUserRep.InsertNowAsync(user);
                userId = backUser.Entity.Id;
            }
            await _userRoleService.GrantRole(user.SysUserInfo.UserId, input.RoleIds);
        }

        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task DeleteUser(List<long> ids)
        {
            List<SysUser> user = await _sysUserRep.AsQueryable().Include(t => t.SysUserInfo).Where(t => ids.Contains(t.Id)).ToListAsync();
            user.ForEach(item =>
            {
                item.Status = (int)CommonStatus.DELETED;
                item.IsDeleted = true;
                item.SysUserInfo.IsDeleted = true;
                _sysUserRep.UpdateAsync(user);
            });
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="oldPassword">原密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns></returns>
        public async Task UpdataPassword(string oldPassword, string newPassword)
        {
            SysUser user = _userManager.User;
            var encryptPasswod = MD5Encryption.Encrypt(oldPassword);
            if (user.Password != encryptPasswod)
            {
                throw new Exception("原密码错误");
            }
            user.Password = MD5Encryption.Encrypt(newPassword);
            await _sysUserRep.UpdateIncludeAsync(user, new[] { "Password" });
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task ResetPassword(long id)
        {
            SysUser user = await _sysUserRep.AsQueryable().FirstOrDefaultAsync(u => u.Id == id);
            user.Password = MD5Encryption.Encrypt("123456");
            await _sysUserRep.UpdateIncludeAsync(user, new[] { "Password" });
        }
    }
}
